package top.jle.wx.proxy.facade.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.filter.PropertyPreFilter;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import top.jle.jpa.basic.exception.BasicCustomException;
import top.jle.jpa.basic.exception.BasicExceptionCode;
import top.jle.jpa.basic.util.ExceptionUtils;
import top.jle.wx.proxy.constant.MenuOption;
import top.jle.wx.proxy.domain.menu.ConditionalMenus;
import top.jle.wx.proxy.domain.menu.Menu;
import top.jle.wx.proxy.exception.ExceptionCode;
import top.jle.wx.proxy.facade.BasicFacade;
import top.jle.wx.proxy.facade.MenuFacade;
import top.jle.wx.proxy.feign.ResultCheckUtil;
import top.jle.wx.proxy.feign.menu.MenuAPIFeign;

import java.util.List;

@Component("menuFacade")
public class MenuFacadeImpl implements MenuFacade {

    private static final Logger LOGGER = LoggerFactory.getLogger(MenuFacadeImpl.class);

    @Autowired
    private MenuAPIFeign menuAPIFeign;

    @Autowired
    private BasicFacade basicFacade;

    @Override
    public void createMenus(List<Menu> menus) {
        JSONObject menuJSON = this.beforeCreate(menus);
        JSONObject result = menuAPIFeign.createMenu(menuJSON);

        if (!ResultCheckUtil.check(result)) {
            LOGGER.error(result.toJSONString());
            throw new BasicCustomException(ExceptionCode.CREATE_MENUS_FAIL);
        } else {
            LOGGER.info(result.toJSONString());
        }
    }

    @Override
    public List<Menu> getMenus() {
        JSONObject result = menuAPIFeign.getMenus();
        if (!ResultCheckUtil.check(result)) {
            throw new BasicCustomException(ExceptionCode.GET_MENU_FAIL);
        }
        JSONArray menus = result.getJSONObject("menu").getJSONArray("button");
        return menus.toJavaList(Menu.class);
    }

    @Override
    public String createConditionalMenus(ConditionalMenus conditionalMenus) {
        if (conditionalMenus == null || CollectionUtils.isEmpty(conditionalMenus.getMenuList()) || conditionalMenus.getMatchRule() == null) {
            throw new BasicCustomException(BasicExceptionCode.INVALID_PARAM);
        }
        JSONObject menuJSON = this.beforeCreate(conditionalMenus.getMenuList());
        menuJSON.put("matchrule", conditionalMenus.getMatchRule());
        JSONObject result = menuAPIFeign.addConditionalMenus(menuJSON);
        LOGGER.info(result.toString());
        if (!ResultCheckUtil.check(result)) {
            throw new BasicCustomException(ExceptionCode.CREATE_CONDITIONAL_MENUS_FAIL);
        }
        return result.getString("menuid");
    }

    private JSONObject beforeCreate(List<Menu> menus) {
        JSONObject json = new JSONObject();

        if (CollectionUtils.isEmpty(menus)) {
            ExceptionUtils.throwInvalidParamException();
        }
        if (menus.size() > MenuOption.MENU_LIMIT) {
            throw new BasicCustomException(ExceptionCode.OUT_OF_MENU_LIMIT);
        }
        JSONArray buttons = new JSONArray();
        for (Menu menu : menus) {
            JSONObject menuObj;

            PropertyPreFilter propertyPreFilter = new SimplePropertyPreFilter(Menu.class, "name", "sub_button");
            if (!CollectionUtils.isEmpty(menu.getSub_button())) {
                //包含子菜单则父菜单仅保留name属性
                menuObj = JSONObject.parseObject(JSON.toJSONString(menu, propertyPreFilter));
            } else {
                menuObj = JSONObject.parseObject(JSON.toJSONString(menu));
            }
            buttons.add(menuObj);
        }
        json.put("button", buttons);
        return json;
    }


    @Override
    public void deleteConditionalMenus(String menuId) {
        if (StringUtils.isBlank(menuId)) {
            ExceptionUtils.throwInvalidParamException();
        }
        JSONObject m = new JSONObject();
        m.put("menuid", menuId);
        JSONObject result = menuAPIFeign.deleteConditionalMenus(m);
        if (!ResultCheckUtil.check(result)) {
            throw new BasicCustomException(ExceptionCode.DEL_CONDITIONAL_MENUS_FAIL);
        }
    }

}
